package net;

import static net.Protocol.TYPE_INT;
import static net.Protocol.TYPE_OBJECT;
import static net.Protocol.TYPE_STRING;

import java.lang.reflect.InvocationTargetException;

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.Channel;

import util.ChannelBufferUtil;

public class DataReceiver {
	public static final int MAX_ARG_LEN = 8;
	
	public Object[] args0 = null;
	public Object[] args1 = new Object[1];
	public Object[] args2 = new Object[2];
	public Object[] args3 = new Object[3];
	public Object[] args4 = new Object[4];
	public Object[] args5 = new Object[5];
	
	public Object[][] argsPool = {args0, args1, args2, args3, args4, args5};
	
	public Dispatcher dispatcher;
	
//	Integer[] intCache = new Integer[MAX_ARG_LEN];
//	Integer[] intCache = new Integer[MAX_ARG_LEN];
	
	public DataReceiver(Dispatcher dispatcher) {
		this.dispatcher = dispatcher;
	}
	
	public void onData(ChannelBuffer data, Channel channel) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, ClassNotFoundException, InstantiationException {
		int command = data.readByte();
		switch (command) {
		case Protocol.COMMAND_RPC:
			handleRPC(data);
			break;
		}
	}
	
	public void handleRPC(ChannelBuffer data) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		String methodName = ChannelBufferUtil.readString(data);
    	int size = data.readByte();
    	int type;
    	Object[] args = new Object[size+1];
    	args[0] = this;
    	for (int i = 1; i <= size; i++) {
    		type = data.readByte();
    		switch (type) {
    		case TYPE_INT:
    			args[i] = data.readInt();
    			break;
    		case TYPE_STRING:
    			args[i] = ChannelBufferUtil.readString(data);
    			break;
    		case TYPE_OBJECT:
    			args[i] = ChannelBufferUtil.readObject(data);
    			break;
    		}
    	}
    	dispatcher.dispatch(methodName, args);
	}
}
